package com.stu.day17;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zy
 * @date 2025/2/18 17:52
 */
public class WaitDemo2 {
    public static void main(String[] args) {
        WaitDemo2 demo= new WaitDemo2();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                demo.printUpper();
            }
        });
        Thread t2 = new Thread(()->demo.printLower());
        Thread t3 = new Thread(demo::printNum);

        t1.start();
        t2.start();
        t3.start();
    }

    // 创建了一个ReentrantLock对象，用来实现线程之间的互斥锁,能够手动加锁和释放锁。
    private Lock lock = new ReentrantLock();

    // Condition是Lock接口的一个工具类，它用来实现线程的通信机制。
    // 一个Lock对象可以有多个Condition对象，用于控制不同条件下线程的等待和通知。
    // c1是一个条件对象，它是通过lock创建的，用于控制和协调打印大写字母的线程。
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();

    //count=0 执行c1   count=1 执行c2  count2执行c3
    private int count;

    public void printUpper(){
        for (char i = 'A'; i <='Z' ; i++) {
            try{
                lock.lock();
                if(count!=0){
                    //让此线程进入到等他阻塞的状态,必须要被其他线程唤醒
                    c1.await();
                }
                System.out.print(i+" ");
                count = 1;
                //唤醒指定的小写字母的线程
                c2.signal();

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }

    public void printLower(){
        for (char i = 'a'; i <='z' ; i++) {
            try{
                lock.lock();
                if(count!=1){
                    //让此线程进入到等他阻塞的状态,必须要被其他线程唤醒
                    c2.await();
                }
                System.out.print(i+" ");
                count = 2;
                //唤醒指定的数字的线程
                c3.signal();

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }

    public void printNum(){
        for (int i = 1; i <=26 ; i++) {
            try{
                lock.lock();
                if(count!=2){
                    //让此线程进入到等他阻塞的状态,必须要被其他线程唤醒
                    c3.await();
                }
                System.out.print(i+" ");
                count = 0;
                //唤醒指定的大写字母的线程
                c1.signal();

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }
}